home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / PlugInManager.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  47.1 KB  |  1,645 lines

  1. // PlugInManager.cpp: implementation of the CPlugInManager class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4.  
  5. #include "stdafx.h"
  6. #include "io.h"
  7. #include "Radiant.h"
  8. #include "PlugInManager.h"
  9. #include "PlugIn.h"
  10. #include "DialogInfo.h"
  11. #include "pakstuff.h"
  12.  
  13. #ifdef _DEBUG
  14. #undef THIS_FILE
  15. static char THIS_FILE[]=__FILE__;
  16. #define new DEBUG_NEW
  17. #endif
  18.  
  19. //////////////////////////////////////////////////////////////////////
  20. // Construction/Destruction
  21. //////////////////////////////////////////////////////////////////////
  22.  
  23. CPlugInManager::CPlugInManager()
  24. {
  25.   m_pTexturePlug = NULL;
  26.   m_pSurfaceListPlug = NULL;
  27.   PatchesMode = EActivePatches;
  28. }
  29.  
  30. CPlugInManager::~CPlugInManager()
  31. {
  32.   Cleanup();
  33. }
  34.  
  35. void CPlugInManager::Init(const char * pPath)
  36. {
  37.     Cleanup();
  38.  
  39.     // set some globals
  40.     g_qeglobals.bSurfacePropertiesPlugin = false;
  41.     g_qeglobals.bBSPFrontendPlugin = false;
  42.     
  43.     CString strPath(pPath);
  44.     strPath += "*.dll";
  45.     
  46.     bool bGo = true;
  47.     
  48.     struct _finddata_t fileinfo;
  49.     int handle = _findfirst (strPath, &fileinfo);
  50.     if (handle != -1)
  51.     {
  52.         do
  53.         {
  54.             strPath.Format("%s\\%s", pPath, fileinfo.name);
  55.             CPlugIn *pPlug = new CPlugIn();
  56.             if (pPlug->load(strPath))
  57.             {
  58.                 if(FillFuncTable(pPlug))        // PGM
  59.                 {
  60.                     m_PlugIns.Add(pPlug);
  61.  
  62.                     pPlug->RegisterPluginEntities();
  63.  
  64.                     // if this thing handles surface properties
  65.                     pPlug->InitSurfacePlugin();
  66.                     
  67.                     // will test and init if it's a BSP frontend
  68.                     pPlug->InitBSPFrontendPlugin();
  69.  
  70.                     g_pParentWnd->AddPlugInMenuItem(pPlug);
  71.                     
  72.                     // if this thing handles textures
  73.                     if (pPlug->getTextureInfo() != NULL)
  74.                     {
  75.                         this->m_pTexturePlug = pPlug;
  76.                         
  77.                         // if this is a wad style texture extension, have it load everything now
  78.                         if (pPlug->getTextureInfo()->m_bWadStyle)
  79.                         {
  80.                             CString strPath = ValueForKey(g_qeglobals.d_project_entity, "texturepath");
  81.                             pPlug->loadTexture(strPath);
  82.                         }
  83.                     }
  84.                     
  85.                     if (pPlug->getSurfaceFlags() != NULL)
  86.                     {
  87.                         this->m_pSurfaceListPlug = pPlug;
  88.                     }
  89.                 }
  90.                 else
  91.                 {
  92.                     delete pPlug;                // PGM
  93.                 }
  94.             }
  95.             else
  96.             {
  97.                 delete pPlug;
  98.             }
  99.         } while (_findnext( handle, &fileinfo ) != -1);
  100.         _findclose (handle);
  101.     }
  102.     
  103. }
  104.  
  105. void CPlugInManager::Cleanup()
  106. {
  107.     int i;
  108.     for (i = 0; i < m_PlugIns.GetSize(); i++)
  109.     {
  110.         CPlugIn *plug = reinterpret_cast<CPlugIn*>(m_PlugIns.GetAt(i));
  111.         plug->free();
  112.         delete plug;
  113.     }
  114.     m_PlugIns.RemoveAll();
  115.     
  116.     for (i = 0; i < m_BrushHandles.GetSize(); i++)
  117.     {
  118.         brush_t *pb = reinterpret_cast<brush_t*>(m_BrushHandles.GetAt(i));
  119.         Brush_Free(pb);
  120.     }
  121.     m_BrushHandles.RemoveAll();
  122.     
  123.     for (i = 0; i < m_EntityHandles.GetSize(); i++)
  124.     {
  125.         entity_t *pe = reinterpret_cast<entity_t*>(m_EntityHandles.GetAt(i));
  126.         Entity_Free(pe);
  127.     }
  128.     m_EntityHandles.RemoveAll();
  129.     
  130.     // patches
  131.     // these are linked into the map
  132.     m_PatchesHandles.RemoveAll();
  133.     // these patches were allocated by Radiant on plugin request
  134.     // if the list is not empty, it means either the plugin asked for allocation and never commited them to the map
  135.     // in which case we are supposed to delete them
  136.     // or it commited them but never called m_pfnReleasePatchHandles, in case the patches may have already been
  137.     // erased and we are trying a second time, therefore crashing ..
  138.     //++timo FIXME: for now I leave a leak warning, we'd need a table to keep track of commited patches
  139. #ifdef _DEBUG
  140.     if (m_PluginPatches.GetSize() != 0)
  141.         Sys_Printf("WARNING: m_PluginPatches.GetSize() != 0 in CPlugInManager::Cleanup, possible leak\n");
  142. #endif
  143. /*    for (i = 0; i < m_PluginPatches.GetSize(); i++)
  144.     {
  145.         patchMesh_t *pMesh = reinterpret_cast<patchMesh_t*>(m_PluginPatches.GetAt(i));
  146.         if (pMesh->pSymbiot)
  147.             delete pMesh;
  148.     }
  149.     m_PluginPatches.RemoveAll(); */
  150. }
  151.  
  152. void CPlugInManager::Dispatch(int n, const char * p)
  153. {
  154.   for (int i = 0; i < m_PlugIns.GetSize(); i++)
  155.   {
  156.     CPlugIn *plug = reinterpret_cast<CPlugIn*>(m_PlugIns.GetAt(i));
  157.     if (plug->ownsCommandID(n))
  158.     {
  159.       vec3_t vMin, vMax;
  160.         if (selected_brushes.next == &selected_brushes)
  161.       {
  162.         vMin[0] = vMin[1] = vMin[2] = 0;
  163.         VectorCopy(vMin, vMax);
  164.       }
  165.       else
  166.       {
  167.         Select_GetBounds (vMin, vMax);
  168.       }
  169.       plug->dispatchCommand(p, vMin, vMax, QE_SingleBrush(true));    // PGM -- added quiet
  170.       break;
  171.     }
  172.   }
  173. }
  174.  
  175. // creates a dummy brush in the active brushes list
  176. // FIXME : is this one really USED ?
  177. void WINAPI QERApp_CreateBrush(vec3_t vMin, vec3_t vMax)
  178. {
  179.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  180.     
  181.     brush_t* pBrush = Brush_Create(vMin, vMax, &g_qeglobals.d_texturewin.texdef);
  182.     Entity_LinkBrush (world_entity, pBrush);
  183.     Brush_Build(pBrush);
  184.     Brush_AddToList (pBrush, &active_brushes);
  185.     Select_Brush(pBrush);
  186.     Sys_UpdateWindows(W_ALL);
  187. }
  188.  
  189. LPVOID CPlugInManager::CreateBrushHandle()
  190. {
  191.     brush_t *pb = Brush_Alloc();
  192.     pb->numberId = g_nBrushId++;
  193.   m_BrushHandles.Add(pb);
  194.   return (LPVOID)pb;
  195. }
  196.  
  197. void CPlugInManager::DeleteBrushHandle(void * vp)
  198. {
  199.   CPtrArray* pHandles[3];
  200.   pHandles[0] = &m_SelectedBrushHandles;
  201.   pHandles[1] = &m_ActiveBrushHandles;
  202.   pHandles[2] = &m_BrushHandles;
  203.  
  204.   for (int j = 0; j < 3; j++)
  205.   {
  206.     for (int i = 0; i < pHandles[j]->GetSize(); i++)
  207.     {
  208.       brush_t *pb = reinterpret_cast<brush_t*>(pHandles[j]->GetAt(i));
  209.       if (pb == reinterpret_cast<brush_t*>(vp))
  210.       {
  211.         if (j == 2)
  212.         {
  213.           // only remove it from the list if it is work area
  214.           // this allows the selected and active list indexes to remain constant
  215.           // throughout a session (i.e. between an allocate and release)
  216.           pHandles[j]->RemoveAt(i);
  217.         }
  218.         Brush_Free(pb);
  219.         Sys_MarkMapModified();        // PGM
  220.         return;
  221.       }
  222.     }
  223.   }
  224. }
  225.  
  226. void CPlugInManager::CommitBrushHandleToMap(void * vp)
  227. {
  228.   g_bScreenUpdates = false; 
  229.   for (int i = 0; i < m_BrushHandles.GetSize(); i++)
  230.   {
  231.     brush_t *pb = reinterpret_cast<brush_t*>(m_BrushHandles.GetAt(i));
  232.     if (pb == reinterpret_cast<brush_t*>(vp))
  233.     {
  234.       m_BrushHandles.RemoveAt(i);
  235.       Entity_LinkBrush (world_entity, pb);
  236.       Brush_Build(pb);
  237.       Brush_AddToList (pb, &active_brushes);
  238.       Select_Brush(pb);
  239.     }
  240.   }
  241.   g_bScreenUpdates = true; 
  242.   Sys_UpdateWindows(W_ALL);
  243. }
  244.  
  245. void CPlugInManager::AddFaceToBrushHandle(void * vp, vec3_t v1, vec3_t v2, vec3_t v3)
  246. {
  247.   brush_t *bp = FindBrushHandle(vp);
  248.   if (bp != NULL)
  249.   {
  250.         face_t *f = Face_Alloc();
  251.         f->texdef = g_qeglobals.d_texturewin.texdef;
  252.         f->texdef.flags &= ~SURF_KEEP;
  253.         f->texdef.contents &= ~CONTENTS_KEEP;
  254.         f->next = bp->brush_faces;
  255.         bp->brush_faces = f;
  256.         VectorCopy (v1, f->planepts[0]);
  257.         VectorCopy (v2, f->planepts[1]);
  258.         VectorCopy (v3, f->planepts[2]);
  259.   }
  260. }
  261.  
  262. brush_t* CPlugInManager::FindBrushHandle(void * vp)
  263. {
  264.   CPtrArray* pHandles[4];
  265.   pHandles[0] = &m_SelectedBrushHandles;
  266.   pHandles[1] = &m_ActiveBrushHandles;
  267.   pHandles[2] = &m_BrushHandles;
  268.   pHandles[3] = &m_EntityBrushHandles;
  269.  
  270.   for (int j = 0; j < 4; j++)
  271.   {
  272.     for (int i = 0; i < pHandles[j]->GetSize(); i++)
  273.     {
  274.       brush_t *pb = reinterpret_cast<brush_t*>(pHandles[j]->GetAt(i));
  275.       if (pb == reinterpret_cast<brush_t*>(vp))
  276.       {
  277.         return pb;
  278.       }
  279.     }
  280.   }
  281.   return NULL;
  282. }
  283.  
  284. patchMesh_t* CPlugInManager::FindPatchHandle(int index)
  285. {
  286.     switch (PatchesMode)
  287.     {
  288.     case EActivePatches:
  289.     case ESelectedPatches:
  290.         if ( index < m_PatchesHandles.GetSize() )
  291.         {
  292.             brush_t *pb = reinterpret_cast<brush_t *>(m_PatchesHandles.GetAt(index));
  293.             return pb->pPatch;
  294.         }
  295. #ifdef _DEBUG
  296.         Sys_Printf("WARNING: out of bounds in CPlugInManager::FindPatchHandle\n");
  297. #endif
  298.         break;
  299.     case EAllocatedPatches:
  300.         if ( index < m_PluginPatches.GetSize() )
  301.         {
  302.             patchMesh_t *pPatch = reinterpret_cast<patchMesh_t *>(m_PluginPatches.GetAt(index));
  303.             return pPatch;
  304.         }
  305. #ifdef _DEBUG
  306.         Sys_Printf("WARNING: out of bounds in CPlugInManager::FindPatchHandle\n");
  307. #endif
  308.         break;
  309.     }
  310.     return NULL;
  311. }
  312.  
  313. LPVOID WINAPI QERApp_CreateBrushHandle()
  314. {
  315.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  316.   return g_pParentWnd->GetPlugInMgr().CreateBrushHandle();
  317. }
  318.  
  319. void WINAPI QERApp_DeleteBrushHandle(LPVOID vp)
  320. {
  321.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  322.   g_pParentWnd->GetPlugInMgr().DeleteBrushHandle(vp);
  323. }
  324.  
  325. void WINAPI QERApp_CommitBrushHandleToMap(LPVOID vp)
  326. {
  327.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  328.   g_pParentWnd->GetPlugInMgr().CommitBrushHandleToMap(vp);
  329. }
  330.  
  331. void WINAPI QERApp_AddFace(LPVOID vp, vec3_t v1, vec3_t v2, vec3_t v3)
  332. {
  333.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  334.   g_pParentWnd->GetPlugInMgr().AddFaceToBrushHandle(vp, v1, v2, v3);
  335. }
  336.  
  337. void WINAPI QERApp_DeleteSelection()
  338. {
  339.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  340.   Select_Delete();
  341. }
  342.  
  343. void WINAPI QERApp_SysMsg(LPCSTR pMsg)
  344. {
  345.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  346.   CString str = pMsg;
  347.   Sys_Printf(str.GetBuffer(0));
  348. }
  349.  
  350. // NOTE: called only in case of plugin error. We can try a plugin refresh instead of a straight crash ?
  351. void WINAPI QERApp_ErrorMsg(LPCSTR pMsg)
  352. {
  353.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  354.     CString str = pMsg;
  355.     Error(str.GetBuffer(0));
  356. }
  357.  
  358. void WINAPI QERApp_InfoMsg(LPCSTR pMsg)
  359. {
  360.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  361.   ShowInfoDialog(pMsg);
  362. }
  363.  
  364. void WINAPI QERApp_HideInfoMsg()
  365. {
  366.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  367.   HideInfoDialog();
  368. }
  369.  
  370. //=====
  371. //PGM
  372. void WINAPI QERApp_PositionView(vec3_t    v1, vec3_t v2)
  373. {
  374.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  375.     g_pParentWnd->ActiveXY()->SetOrigin(v1);
  376.     // FIXME - implement this!
  377.     Sys_UpdateWindows(W_ALL);
  378. }
  379. //PGM
  380. //=====
  381.  
  382. //FIXME: this AcquirePath stuff is pretty much a mess and needs cleaned up
  383. bool g_bPlugWait = false;
  384. bool g_bPlugOK = false;
  385. int  g_nPlugCount = 0;
  386.  
  387. void _PlugDone(bool b, int n)
  388. {
  389.   g_bPlugWait = false;
  390.   g_bPlugOK = b;
  391.   g_nPlugCount = n;
  392. }
  393.  
  394. void WINAPI QERApp_GetPoints(int nMax, _QERPointData *pData, LPCSTR pMsg)
  395. {
  396.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  397.   ShowInfoDialog(pMsg);
  398.   g_bPlugWait = true;
  399.   g_bPlugOK = false;
  400.   g_nPlugCount = 0;
  401. //  g_nPlugCount=nMax-1;
  402.   AcquirePath(nMax, &_PlugDone);
  403.   while (g_bPlugWait)
  404.   {
  405.     MSG msg;
  406.     if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) 
  407.     { 
  408.       TranslateMessage(&msg);
  409.       DispatchMessage(&msg);
  410.     }
  411.   }
  412.   HideInfoDialog();
  413.   
  414.   pData->m_nCount = 0;
  415.   pData->m_pVectors = NULL;
  416.  
  417.   if (g_bPlugOK && g_nPlugCount > 0)
  418.   {
  419.     pData->m_nCount = g_nPlugCount;
  420.     pData->m_pVectors = reinterpret_cast<vec3_t*>(qmalloc(g_nPlugCount * sizeof(vec3_t)));
  421.     vec3_t *pOut = pData->m_pVectors;
  422.     for (int i = 0; i < g_nPlugCount; i++)
  423.     {
  424.     memcpy(pOut, &g_PathPoints[i],sizeof(vec3_t));
  425.     pOut++;
  426.     }
  427.   }
  428. }
  429.  
  430. void WINAPI QERApp_AddFaceData(LPVOID pv, _QERFaceData *pData)
  431. {
  432.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  433.  
  434.     brush_t* pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv);
  435.   if (pBrush != NULL)
  436.   {
  437.         face_t *f = Face_Alloc();
  438.         f->texdef = g_qeglobals.d_texturewin.texdef;
  439.         f->texdef.flags = pData->m_nFlags;
  440.     f->texdef.contents = pData->m_nContents;
  441.     f->texdef.value = pData->m_nValue;
  442.     f->texdef.rotate = pData->m_fRotate;
  443.     f->texdef.shift[0] = pData->m_fShift[0];
  444.     f->texdef.shift[1] = pData->m_fShift[1];
  445.     f->texdef.scale[0] = pData->m_fScale[0];
  446.     f->texdef.scale[1] = pData->m_fScale[1];
  447.     //strcpy(f->texdef.name, pData->m_TextureName);
  448.     f->texdef.SetName(pData->m_TextureName);
  449.         f->next = pBrush->brush_faces;
  450.         pBrush->brush_faces = f;
  451.         VectorCopy (pData->m_v1, f->planepts[0]);
  452.         VectorCopy (pData->m_v2, f->planepts[1]);
  453.         VectorCopy (pData->m_v3, f->planepts[2]);
  454.         Sys_MarkMapModified();        // PGM
  455.   }
  456. }
  457.  
  458. int WINAPI QERApp_GetFaceCount(LPVOID pv)
  459. {
  460.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  461.   int n = 0;
  462.   brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv);
  463.   if (pBrush != NULL)
  464.   {
  465.       for (face_t *f = pBrush->brush_faces ; f; f = f->next)
  466.     {
  467.       n++;
  468.     }
  469.   }
  470.   return n;
  471. }
  472.  
  473. _QERFaceData* WINAPI QERApp_GetFaceData(LPVOID pv, int nFaceIndex)
  474. {
  475.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  476.   static _QERFaceData face;
  477.   int n = 0;
  478.   brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv);
  479.  
  480.   if (pBrush != NULL)
  481.   {
  482.     for (face_t *f = pBrush->brush_faces ; f; f = f->next)
  483.     {
  484.  
  485. #ifdef _DEBUG
  486.         if (!pBrush->brush_faces)
  487.         {
  488.             Sys_Printf( "Warning : pBrush->brush_faces is NULL in QERApp_GetFaceData\n" );
  489.             return NULL;
  490.         }
  491. #endif
  492.  
  493.       if (n == nFaceIndex)
  494.       {
  495.         face.m_nContents = f->texdef.contents;
  496.         face.m_nFlags = f->texdef.flags;
  497.         face.m_fRotate = f->texdef.rotate;
  498.         face.m_fScale[0] = f->texdef.scale[0];
  499.         face.m_fScale[1] = f->texdef.scale[1];
  500.         face.m_fShift[0] = f->texdef.shift[0];
  501.         face.m_fShift[1] = f->texdef.shift[1];
  502.         face.m_nValue = f->texdef.value;
  503.         strcpy(face.m_TextureName, f->texdef.name);
  504.         VectorCopy(f->planepts[0], face.m_v1);
  505.         VectorCopy(f->planepts[1], face.m_v2);
  506.         VectorCopy(f->planepts[2], face.m_v3);
  507.         return &face;
  508.       }
  509.       n++;
  510.     }
  511.   }
  512.   return NULL;
  513. }
  514.  
  515. void WINAPI QERApp_SetFaceData(LPVOID pv, int nFaceIndex, _QERFaceData *pData)
  516. {
  517.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  518.     int n = 0;
  519.     brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv);
  520.  
  521.     if (pBrush != NULL)
  522.     {
  523.         for (face_t *f = pBrush->brush_faces ; f; f = f->next)
  524.         {
  525.             if (n == nFaceIndex)
  526.             {
  527.                 f->texdef.flags = pData->m_nFlags;
  528.                 f->texdef.contents = pData->m_nContents;
  529.                 f->texdef.value = pData->m_nValue;
  530.                 f->texdef.rotate = pData->m_fRotate;
  531.                 f->texdef.shift[0] = pData->m_fShift[0];
  532.                 f->texdef.shift[1] = pData->m_fShift[1];
  533.                 f->texdef.scale[0] = pData->m_fScale[0];
  534.                 f->texdef.scale[1] = pData->m_fScale[1];
  535.                 //strcpy(f->texdef.name, pData->m_TextureName);
  536.                 f->texdef.SetName(pData->m_TextureName);
  537.                 VectorCopy(pData->m_v1, f->planepts[0]);
  538.                 VectorCopy(pData->m_v2, f->planepts[1]);
  539.                 VectorCopy(pData->m_v3, f->planepts[2]);
  540.                 Sys_MarkMapModified();        // PGM
  541.                 return;                        // PGM
  542.             }
  543.             n++;
  544.         }
  545.     }
  546. }
  547.  
  548. void WINAPI QERApp_DeleteFace(LPVOID pv, int nFaceIndex)
  549. {
  550.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  551.   int n = 0;
  552.   brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv);
  553.   if (pBrush != NULL)
  554.   {
  555.     face_t *pPrev = pBrush->brush_faces;
  556.       for (face_t *f = pBrush->brush_faces; f; f = f->next)
  557.     {
  558.       if (n == nFaceIndex)
  559.       {
  560.         pPrev->next = f->next;
  561.               Face_Free (f);
  562.         Sys_MarkMapModified();        // PGM
  563.         return;
  564.       }
  565.       n++;
  566.       pPrev = f;
  567.     }
  568.   }
  569. }
  570.  
  571. //==========
  572. //PGM
  573. void WINAPI QERApp_BuildBrush (LPVOID pv)
  574. {
  575.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  576.     brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv);
  577.     if (pBrush != NULL)
  578.     {
  579.         Brush_Build(pBrush);
  580.         Sys_UpdateWindows(W_ALL);
  581.     }
  582. }
  583.  
  584. //Timo : another version with bConvert flag
  585. //++timo since 1.7 is not compatible with earlier plugin versions, remove this one and update QERApp_BuildBrush
  586. void WINAPI QERApp_BuildBrush2 (LPVOID pv, int bConvert)
  587. {
  588.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  589.     brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv);
  590.     if (pBrush != NULL)
  591.     {
  592.         Brush_Build( pBrush, true, true, bConvert );
  593.         Sys_UpdateWindows(W_ALL);
  594.     }
  595. }
  596.  
  597. void WINAPI QERApp_SelectBrush (LPVOID pv)
  598. {
  599.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  600.     brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv);
  601.     if (pBrush != NULL)
  602.     {
  603.         Select_Brush(pBrush, false);
  604.         Sys_UpdateWindows(W_ALL);
  605.     }
  606.  
  607. }
  608.  
  609. void WINAPI QERApp_DeselectBrush (LPVOID pv)
  610. {
  611.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  612.     // FIXME - implement this!
  613. }
  614.  
  615. void WINAPI QERApp_ResetPlugins()
  616. {
  617.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  618.   g_pParentWnd->OnPluginsRefresh();
  619. }
  620.  
  621. void WINAPI QERApp_DeselectAllBrushes ()
  622. {
  623.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  624.     Select_Deselect();
  625.     Sys_UpdateWindows(W_ALL);
  626. }
  627. //PGM
  628. //==========
  629.  
  630. void WINAPI QERApp_TextureBrush(LPVOID pv, LPCSTR pName)
  631. {
  632.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  633.   brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv);
  634.   if (pBrush != NULL)
  635.   {
  636.       for (face_t *f = pBrush->brush_faces ; f; f = f->next)
  637.     {
  638.       //strcpy(f->texdef.name, pName);
  639.       f->texdef.SetName(pName);
  640.     }
  641.     Sys_MarkMapModified();        // PGM
  642.   }
  643. }
  644.  
  645. int WINAPI QERApp_SelectedBrushCount()
  646. {
  647.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  648.   int n = 0;
  649.     for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next)
  650.     {
  651.     n++;
  652.   }
  653.   return n;
  654. }
  655.  
  656. int WINAPI QERApp_ActiveBrushCount()
  657. {
  658.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  659.   int n = 0;
  660.     for (brush_t *pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next)
  661.     {
  662.     n++;
  663.   }
  664.   return n;
  665. }
  666.  
  667. int WINAPI QERApp_AllocateSelectedBrushHandles()
  668. {
  669.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  670.   int n = 0;
  671.     for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next)
  672.     {
  673.     n++;
  674.     g_pParentWnd->GetPlugInMgr().GetSelectedHandles().Add(pb);
  675.   }
  676.   return n;
  677. }
  678.  
  679. int WINAPI QERApp_AllocateActiveBrushHandles()
  680. {
  681.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  682.   int n = 0;
  683.     for (brush_t *pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next)
  684.     {
  685.     n++;
  686.     g_pParentWnd->GetPlugInMgr().GetActiveHandles().Add(pb);
  687.   }
  688.   return n;
  689. }
  690.  
  691. void WINAPI QERApp_ReleaseSelectedBrushHandles()
  692. {
  693.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  694.   g_pParentWnd->GetPlugInMgr().GetSelectedHandles().RemoveAll();
  695.   Sys_UpdateWindows(W_ALL);
  696. }
  697.  
  698. void WINAPI QERApp_ReleaseActiveBrushHandles()
  699. {
  700.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  701.   g_pParentWnd->GetPlugInMgr().GetActiveHandles().RemoveAll();
  702.   Sys_UpdateWindows(W_ALL);
  703. }
  704.  
  705. LPVOID WINAPI QERApp_GetActiveBrushHandle(int nIndex)
  706. {
  707.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  708.   if (nIndex < g_pParentWnd->GetPlugInMgr().GetActiveHandles().GetSize())
  709.   {
  710.     return reinterpret_cast<LPVOID>(g_pParentWnd->GetPlugInMgr().GetActiveHandles().GetAt(nIndex));
  711.   }
  712.   return NULL;
  713. }
  714.  
  715. LPVOID WINAPI QERApp_GetSelectedBrushHandle(int nIndex)
  716. {
  717.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  718.   if (nIndex < g_pParentWnd->GetPlugInMgr().GetSelectedHandles().GetSize())
  719.   {
  720.     return reinterpret_cast<LPVOID>(g_pParentWnd->GetPlugInMgr().GetSelectedHandles().GetAt(nIndex));
  721.   }
  722.   return NULL;
  723. }
  724.  
  725. int WINAPI QERApp_TextureCount()
  726. {
  727.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  728.     Texture_StartPos ();
  729.   int x, y;
  730.   int n = 0;
  731.     while (1)
  732.     {
  733.         qtexture_t *q = Texture_NextPos (&x, &y);
  734.         if (!q)
  735.             break;
  736.     n++;
  737.   }
  738.   return n;
  739. }
  740.  
  741. LPCSTR WINAPI QERApp_GetTexture(int nIndex)
  742. {
  743.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  744.   static char name[QER_MAX_NAMELEN];
  745.     Texture_StartPos ();
  746.   int x, y;
  747.   int n = 0;
  748.     while (1)
  749.     {
  750.         qtexture_t *q = Texture_NextPos (&x, &y);
  751.         if (!q)
  752.             break;
  753.     if (n == nIndex)
  754.     {
  755.       strcpy(name, q->name);
  756.       return name;
  757.     }
  758.     n++;
  759.   }
  760.   return NULL;
  761. }
  762.  
  763. LPCSTR WINAPI QERApp_GetCurrentTexture()
  764. {
  765.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  766.   return g_qeglobals.d_texturewin.texdef.name;
  767. }
  768.  
  769. void WINAPI QERApp_SetCurrentTexture(LPCSTR strName)
  770. {
  771.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  772.     //++timo hu ?? tex is not initialized ?? can be any value ..
  773.   texdef_t tex;
  774.   //++timo added a brushprimit_texdef ..
  775.   // smthg to be done here
  776.   brushprimit_texdef_t brushprimit_tex;
  777.   //strcpy(tex.name, strName);
  778.   tex.SetName(strName);
  779.   Texture_SetTexture(&tex,&brushprimit_tex);
  780. }
  781.  
  782. int WINAPI QERApp_GetEClassCount()
  783. {
  784.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  785.   int n = 0;
  786.   for (eclass_t *e = eclass ; e ; e = e->next)
  787.     {
  788.     n++;
  789.   }
  790.   return n;
  791. }
  792.  
  793. LPCSTR WINAPI QERApp_GetEClass(int nIndex)
  794. {
  795.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  796.   int n = 0;
  797.   for (eclass_t *e = eclass ; e ; e = e->next)
  798.     {
  799.     if (n == nIndex)
  800.     {
  801.       return e->name;
  802.     }
  803.   }
  804.   return NULL;
  805. }
  806.  
  807. void WINAPI QERApp_LoadTextureRGBA(LPVOID vp)
  808. {
  809.   Texture_LoadFromPlugIn(vp);
  810. }
  811.  
  812. // v1.70 code
  813. // world_entity holds the worldspawn and is indexed as 0
  814. // other entities are in the entities doubly linked list
  815. // QERApp_GetEntityCount counts the entities like in any C array: [0..length-1]
  816. int WINAPI QERApp_GetEntityCount()
  817. {
  818.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  819.     int n = 1;
  820.     for (entity_t *pe = entities.next ; pe != &entities ; pe = pe->next)
  821.     {
  822.         n++;
  823.     }
  824.     return n;
  825. }
  826.  
  827. // We don't store entities in CPtrArray, we need to walk the list
  828. LPVOID WINAPI QERApp_GetEntityHandle(int nIndex)
  829. {
  830.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  831.     if (nIndex==0)
  832.         // looks for the worldspawn
  833.         return static_cast<LPVOID>(world_entity);
  834.     entity_t *pe = &entities;
  835.     int n = 0;
  836.     while ( n < nIndex )
  837.     {
  838.         pe = pe->next;
  839.         n++;
  840.     }
  841.     return static_cast<LPVOID>(pe);
  842. }
  843.  
  844. epair_t** WINAPI QERApp_GetEntityKeyValList(LPVOID vp)
  845. {
  846.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  847.     entity_t *pe = static_cast<entity_t *>(vp);
  848.     return &pe->epairs;
  849. }
  850.  
  851. epair_t* WINAPI QERApp_AllocateEpair( char *key, char *val )
  852. {
  853.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  854.     epair_t *e = (epair_t*)qmalloc (sizeof(*e));
  855.     e->key = (char*)qmalloc(strlen(key)+1);
  856.     strcpy (e->key, key);
  857.     e->value = (char*)qmalloc(strlen(val)+1);
  858.     strcpy (e->value, val);
  859.     return e;
  860. }
  861.  
  862. void WINAPI QERApp_SetEntityKeyValList(LPVOID vp, epair_t* ep)
  863. {
  864.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  865.     entity_t *pe = static_cast<entity_t *>(vp);
  866.     if (pe->epairs)
  867.         Sys_Printf( "Warning : pe->epairs != NULL in QERApp_SetEntityKeyValList, will not set\n" );
  868.     else
  869.         pe->epairs = ep;
  870. }
  871.  
  872. int WINAPI QERApp_AllocateEntityBrushHandles(LPVOID vp)
  873. {
  874.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  875.     entity_t *pe = static_cast<entity_t *>(vp);
  876.     int n = 0;
  877.     if (!pe->brushes.onext)
  878.         return 0;
  879.     g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().RemoveAll();
  880.     for (brush_t *pb = pe->brushes.onext ; pb != &pe->brushes ; pb=pb->onext)
  881.     {
  882.         n++;
  883.         g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().Add(pb);
  884.     }
  885.     return n;
  886. }
  887.     
  888. void WINAPI QERApp_ReleaseEntityBrushHandles()
  889. {
  890.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  891.     g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().RemoveAll();
  892. }
  893.  
  894. LPVOID WINAPI QERApp_GetEntityBrushHandle(int nIndex)
  895. {
  896.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  897.     if (nIndex < g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().GetSize())
  898.         return g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().GetAt(nIndex);
  899.     return NULL;
  900. }
  901.  
  902. LPVOID WINAPI QERApp_CreateEntityHandle()
  903. {
  904.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  905.     entity_t *pe = reinterpret_cast<entity_t*>(qmalloc(sizeof(entity_t)));
  906.     pe->brushes.onext = pe->brushes.oprev = &pe->brushes;
  907.     g_pParentWnd->GetPlugInMgr().GetEntityHandles().Add(static_cast<LPVOID>(pe));
  908.     return static_cast<LPVOID>(pe);
  909. }
  910.  
  911. // the vpBrush needs to be in m_BrushHandles
  912. //++timo we don't have allocation nor storage for vpEntity, no checks for this one
  913. void WINAPI QERApp_CommitBrushHandleToEntity(LPVOID vpBrush, LPVOID vpEntity)
  914. {
  915.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  916.     g_pParentWnd->GetPlugInMgr().CommitBrushHandleToEntity(vpBrush, vpEntity);
  917.     return;
  918. }
  919.  
  920. char* WINAPI QERApp_ReadProjectKey(char* key)
  921. {
  922.     return ValueForKey(g_qeglobals.d_project_entity, key);
  923. }
  924.  
  925. int WINAPI QERApp_ScanFileForEClass(char *filename )
  926. {
  927.     // set single class parsing
  928.     parsing_single = true;
  929.     Eclass_ScanFile(filename);
  930.     if (eclass_found)
  931.     {
  932.         eclass_e->nShowFlags |= ECLASS_PLUGINENTITY;
  933.         return 1;
  934.     }
  935.     return 0;
  936. }
  937.  
  938. // the vpBrush needs to be in m_BrushHandles
  939. //++timo add a debug check to see if we found the brush handle
  940. // NOTE : seems there's no way to check vpEntity is valid .. this is dangerous
  941. // links the brush to its entity, everything else is done when commiting the entity to the map
  942. void CPlugInManager::CommitBrushHandleToEntity(LPVOID vpBrush, LPVOID vpEntity)
  943. {
  944.     brush_t* pb;
  945.     entity_t* pe;
  946.     for (int i=0 ; i < m_BrushHandles.GetSize() ; i++)
  947.     {
  948.         if (vpBrush == m_BrushHandles.GetAt(i))
  949.         {
  950.             m_BrushHandles.RemoveAt(i);
  951.             pb = reinterpret_cast<brush_t*>(vpBrush);
  952.             pe = reinterpret_cast<entity_t *>(vpEntity);
  953.             Entity_LinkBrush (pe, pb);
  954.         }
  955.     }
  956.     Sys_UpdateWindows(W_ALL);
  957. }
  958.  
  959. // the vpEntity must be in m_EntityHandles
  960. void WINAPI QERApp_CommitEntityHandleToMap(LPVOID vpEntity)
  961. {
  962.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  963.     g_pParentWnd->GetPlugInMgr().CommitEntityHandleToMap(vpEntity);
  964.     return;
  965. }
  966.  
  967. int WINAPI QERApp_LoadFile( const char *pLocation, void ** buffer )
  968. {
  969.     char cPath[1024];
  970.     sprintf( cPath, "%s/%s", ValueForKey(g_qeglobals.d_project_entity, "basepath"), pLocation);
  971.   int nSize = LoadFile( cPath, buffer);
  972.   if (nSize == -1)
  973.   {
  974.     nSize = PakLoadAnyFile(cPath, buffer);
  975.   }
  976.     return nSize;
  977. }
  978.  
  979. char * WINAPI QERApp_ExpandReletivePath (char *p)
  980. {
  981.     return ExpandReletivePath(p);
  982. }
  983.  
  984. // NOTE: this is a simplified version
  985. int WINAPI QERApp_HasShader( const char *pName )
  986. {
  987.     CShaderInfo *pInfo = hasShader( pName );
  988.     if (pInfo)
  989.         return 1;
  990.     return 0;
  991. }
  992.  
  993. qtexture_t* WINAPI QERApp_Texture_ForName (const char *name)
  994. {
  995.     // if the texture is not loaded yet, this call will get it loaded
  996.     // but: when we assign a GL bind number, we need to be in the g_qeglobals.d_hdcBase , g_qeglobals.d_hglrcBase GL context
  997.     // the plugin may set the GL context to whatever he likes, but then load would fail
  998.     // NOTE: is context switching time-consuming? then maybe the plugin could handle the context switch and only add a 
  999.     // sanity check in debug mode here
  1000.     // read current context
  1001.     HDC pluginHDC = qwglGetCurrentDC();
  1002.     HGLRC pluginHGLRC = qwglGetCurrentContext();
  1003.     qwglMakeCurrent( g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase );
  1004.     qtexture_t* qtex = Texture_ForName( name );
  1005.     return qtex;
  1006.     qwglMakeCurrent( pluginHDC, pluginHGLRC );
  1007. }
  1008.  
  1009. void WINAPI QERApp_RadiantFree( void * buf )
  1010. {
  1011.     free( buf );
  1012. }
  1013.  
  1014. char* WINAPI QERApp_Token()
  1015. {
  1016.     return token;
  1017. }
  1018.  
  1019. char* WINAPI QERApp_GetMapName()
  1020. {
  1021.     return currentmap;
  1022. }
  1023.  
  1024. void CPlugInManager::CommitEntityHandleToMap(LPVOID vpEntity)
  1025. {
  1026.     entity_t *pe;
  1027.     eclass_t *e;
  1028.     brush_t        *b;
  1029.     vec3_t mins,maxs;
  1030.     bool has_brushes;
  1031.     for (int i=0 ; i < m_EntityHandles.GetSize() ; i++ )
  1032.     {
  1033.         if (vpEntity == m_EntityHandles.GetAt(i))
  1034.         {
  1035.             m_EntityHandles.RemoveAt(i);
  1036.             pe = reinterpret_cast<entity_t*>(vpEntity);
  1037.             // fill additional fields
  1038.             // straight copy from Entity_Parse
  1039.             // entity_t::origin
  1040.             GetVectorForKey (pe, "origin", pe->origin);
  1041.             // entity_t::eclass
  1042.             if (pe->brushes.onext == &pe->brushes)
  1043.                 has_brushes = false;
  1044.             else
  1045.                 has_brushes = true;
  1046.             e = Eclass_ForName (ValueForKey (pe, "classname"), has_brushes);
  1047.             pe->eclass = e;
  1048.             // fixedsize
  1049.             if (e->fixedsize)
  1050.             {
  1051.                 if (pe->brushes.onext != &pe->brushes)
  1052.                 {
  1053.                     Sys_Printf("Warning : Fixed size entity with brushes in CPlugInManager::CommitEntityHandleToMap\n");
  1054.                 }
  1055.                 // create a custom brush
  1056.                 VectorAdd(e->mins, pe->origin, mins);
  1057.                 VectorAdd(e->maxs, pe->origin, maxs);
  1058.                 float a = 0;
  1059.                 if (e->nShowFlags & ECLASS_MISCMODEL)
  1060.                 {
  1061.                     char* p = ValueForKey(pe, "model");
  1062.                     if (p != NULL && strlen(p) > 0)
  1063.                     {
  1064.                         vec3_t vMin, vMax;
  1065.                         a = FloatForKey (pe, "angle");
  1066.                         if (GetCachedModel(pe, p, vMin, vMax))
  1067.                         {
  1068.                               // create a custom brush
  1069.                               VectorAdd (pe->md3Class->mins, pe->origin, mins);
  1070.                               VectorAdd (pe->md3Class->maxs, pe->origin, maxs);
  1071.                         }
  1072.                     }
  1073.                 }
  1074.         
  1075.                 b = Brush_Create (mins, maxs, &e->texdef);
  1076.  
  1077.                 if (a)
  1078.                 {
  1079.                     vec3_t vAngle;
  1080.                     vAngle[0] = vAngle[1] = 0;
  1081.                     vAngle[2] = a;
  1082.                     Brush_Rotate(b, vAngle, pe->origin, false);
  1083.                 }
  1084.  
  1085.                 b->owner = pe;
  1086.  
  1087.                 b->onext = pe->brushes.onext;
  1088.                 b->oprev = &pe->brushes;
  1089.                 pe->brushes.onext->oprev = b;
  1090.                 pe->brushes.onext = b;
  1091.             }
  1092.             else
  1093.             {    // brush entity
  1094.                 if (pe->brushes.next == &pe->brushes)
  1095.                     Sys_Printf ("Warning: Brush entity with no brushes in CPlugInManager::CommitEntityHandleToMap\n");
  1096.             }
  1097.  
  1098.             // add brushes to the active brushes list
  1099.             // and build them along the way
  1100.             for (b=pe->brushes.onext ; b != &pe->brushes ; b=b->onext)
  1101.             {
  1102.                 // convert between old brushes and brush primitive
  1103.                 if (g_qeglobals.m_bBrushPrimitMode)
  1104.                 {
  1105.                     // we only filled the shift scale rot fields, needs conversion
  1106.                     Brush_Build( b, true, true, true );
  1107.                 }
  1108.                 else
  1109.                 {
  1110.                     // we are using old brushes
  1111.                     Brush_Build( b );
  1112.                 }
  1113.                 b->next = active_brushes.next;
  1114.                 active_brushes.next->prev = b;
  1115.                 b->prev = &active_brushes;
  1116.                 active_brushes.next = b;
  1117.             }
  1118.  
  1119.             // handle worldspawn entities
  1120.             // if worldspawn has no brushes, use the new one
  1121.             if (!strcmp(ValueForKey (pe, "classname"), "worldspawn"))
  1122.             {
  1123.                 if ( world_entity && ( world_entity->brushes.onext != &world_entity->brushes ) )
  1124.                 {
  1125.                     // worldspawn already has brushes
  1126.                     Sys_Printf ("Commiting worldspawn as func_group\n");
  1127.                     SetKeyValue(pe, "classname", "func_group");
  1128.                     // add the entity to the end of the entity list
  1129.                     pe->next = &entities;
  1130.                     pe->prev = entities.prev;
  1131.                     entities.prev->next = pe;
  1132.                     entities.prev = pe;
  1133.                     g_qeglobals.d_num_entities++;
  1134.                 }
  1135.                 else
  1136.                 {
  1137.                     // there's a worldspawn with no brushes, we assume the map is empty
  1138.                     if ( world_entity )
  1139.                     {
  1140.                         Entity_Free( world_entity );
  1141.                         world_entity = pe;
  1142.                     }
  1143.                     else
  1144.                         Sys_Printf("Warning : unexpected world_entity == NULL in CommitEntityHandleToMap\n");
  1145.                 }
  1146.             }
  1147.             else
  1148.             {
  1149.                 // add the entity to the end of the entity list
  1150.                 pe->next = &entities;
  1151.                 pe->prev = entities.prev;
  1152.                 entities.prev->next = pe;
  1153.                 entities.prev = pe;
  1154.                 g_qeglobals.d_num_entities++;
  1155.             }
  1156.         }
  1157.     }
  1158. }
  1159.  
  1160. void WINAPI QERApp_SetScreenUpdate(int bScreenUpdates)
  1161. {
  1162.     g_bScreenUpdates = bScreenUpdates; 
  1163. }
  1164.  
  1165. texturewin_t* WINAPI QERApp_QeglobalsTexturewin()
  1166. {
  1167.     return &g_qeglobals.d_texturewin;
  1168. }
  1169.  
  1170. _QERTextureInfo* CPlugInManager::GetTextureInfo()
  1171. {
  1172.   if (m_pTexturePlug != NULL)
  1173.   {
  1174.     return m_pTexturePlug->getTextureInfo();
  1175.   }
  1176.   else
  1177.   {
  1178.     return NULL;
  1179.   }
  1180. }
  1181.  
  1182. LPVOID CPlugInManager::GetSurfaceFlags()
  1183. {
  1184.   if (m_pSurfaceListPlug != NULL)
  1185.   {
  1186.     return m_pSurfaceListPlug->getSurfaceFlags();
  1187.   }
  1188.   else
  1189.   {
  1190.     return NULL;
  1191.   }
  1192. }
  1193.  
  1194. void CPlugInManager::LoadTexture(const char *pFilename)
  1195. {
  1196.   if (m_pTexturePlug != NULL)
  1197.   {
  1198.     m_pTexturePlug->loadTexture(pFilename);
  1199.   }
  1200. }
  1201.  
  1202. patchMesh_t* WINAPI QERApp_GetSelectedPatch( )
  1203. {
  1204.     for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next)
  1205.     {
  1206.         if (pb->patchBrush)
  1207.         {
  1208.             return pb->pPatch;
  1209.         }
  1210.     }
  1211. #ifdef _DEBUG
  1212.     Sys_Printf("WARNING: QERApp_GetSelectedPatchTexdef called with no patch selected\n");
  1213. #endif
  1214.     return NULL;
  1215. }
  1216.  
  1217. char* WINAPI QERApp_GetGamePath()
  1218. {
  1219.     return g_PrefsDlg.m_strQuake2.GetBuffer(0);
  1220. }
  1221.  
  1222. char* WINAPI QERApp_GetQERPath()
  1223. {
  1224.     return g_strAppPath.GetBuffer(0);
  1225. }
  1226.  
  1227. // patches in/out -----------------------------------
  1228. int WINAPI QERApp_AllocateActivePatchHandles()
  1229. {
  1230.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1231.     return g_pParentWnd->GetPlugInMgr().AllocateActivePatchHandles();
  1232. }
  1233.  
  1234. int CPlugInManager::AllocateActivePatchHandles()
  1235. {
  1236.     int n = 0;
  1237.     for (brush_t *pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next)
  1238.     {
  1239.         if (pb->patchBrush)
  1240.         {
  1241.             n++;
  1242.             m_PatchesHandles.Add(pb);
  1243.         }
  1244.     }
  1245.     return n;
  1246. }
  1247.  
  1248. int WINAPI QERApp_AllocateSelectedPatchHandles()
  1249. {
  1250.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1251.     return g_pParentWnd->GetPlugInMgr().AllocateSelectedPatchHandles();
  1252. }
  1253.     
  1254. int CPlugInManager::AllocateSelectedPatchHandles()
  1255. {
  1256.     int n = 0;
  1257.     for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next)
  1258.     {
  1259.         if (pb->patchBrush)
  1260.         {
  1261.             n++;
  1262.             m_PatchesHandles.Add(pb);
  1263.         }
  1264.     }
  1265.     return n;
  1266. }
  1267.  
  1268. void WINAPI QERApp_ReleasePatchHandles()
  1269. {
  1270.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1271.     g_pParentWnd->GetPlugInMgr().ReleasePatchesHandles();
  1272. }
  1273.  
  1274. patchMesh_t* WINAPI QERApp_GetPatchData(int index)
  1275. {
  1276.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1277.     static patchMesh_t patch;
  1278.     patchMesh_t *pPatch = g_pParentWnd->GetPlugInMgr().FindPatchHandle(index);
  1279.     if (pPatch)
  1280.     {
  1281.         memcpy( &patch, pPatch, sizeof(patchMesh_t) );
  1282.         return &patch;
  1283.     }
  1284.     return NULL;
  1285. }
  1286.  
  1287. void WINAPI QERApp_DeletePatch(int index)
  1288. {
  1289.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1290.     patchMesh_t *pPatch = g_pParentWnd->GetPlugInMgr().FindPatchHandle(index);
  1291.     if (pPatch)
  1292.     {
  1293.         brush_t *pb = pPatch->pSymbiot;
  1294.         Patch_Delete( pPatch );
  1295.         if (pb)
  1296.             Brush_Free( pb );
  1297.     }
  1298. #ifdef _DEBUG
  1299.     Sys_Printf("Warning: QERApp_DeletePatch: FindPatchHandle failed\n");
  1300. #endif
  1301. }
  1302.  
  1303. int WINAPI QERApp_CreatePatchHandle()
  1304. {
  1305.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1306.     return g_pParentWnd->GetPlugInMgr().CreatePatchHandle();
  1307. }
  1308.  
  1309. int CPlugInManager::CreatePatchHandle()
  1310. {
  1311.     // NOTE: we can't call the AddBrushForPatch until we have filled the patchMesh_t structure
  1312.     patchMesh_t *pPatch = MakeNewPatch();
  1313.     m_PluginPatches.Add( pPatch );
  1314.     // change mode
  1315.     PatchesMode = EAllocatedPatches;
  1316.     return m_PluginPatches.GetSize()-1;
  1317. }
  1318.  
  1319. void WINAPI QERApp_CommitPatchHandleToMap(int index, patchMesh_t *pMesh, char *texName)
  1320. {
  1321.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1322.     g_pParentWnd->GetPlugInMgr().CommitPatchHandleToMap(index, pMesh, texName);
  1323. }
  1324.  
  1325. void CPlugInManager::CommitPatchHandleToMap(int index, patchMesh_t *pMesh, char *texName)
  1326. {
  1327.     if (PatchesMode==EAllocatedPatches)
  1328.     {
  1329.         patchMesh_t *pPatch = reinterpret_cast<patchMesh_t *>( m_PluginPatches.GetAt(index) );
  1330.         memcpy( pPatch, pMesh, sizeof( patchMesh_t ) );
  1331.         // patch texturing, if none given use current texture
  1332.         if (texName)
  1333.             pPatch->d_texture = Texture_ForName(texName);
  1334.         if ( !pPatch->d_texture )
  1335.         {
  1336.             pPatch->d_texture = Texture_ForName(g_qeglobals.d_texturewin.texdef.name);
  1337.             // checking .. just in case
  1338.             if (!pPatch->d_texture)
  1339.             {
  1340. #ifdef _DEBUG
  1341.                 Sys_Printf("WARNING: failed to set patch to current texture in CPlugInManager::CommitPatchHandleToMap\n");
  1342. #endif
  1343.                 pPatch->d_texture = notexture;
  1344.             }
  1345.         }
  1346.         g_bScreenUpdates = false;
  1347.         // the bLinkToWorld flag in AddBrushForPatch takes care of Brush_AddToList Entity_linkBrush and Brush_Build
  1348.         brush_t *pb = AddBrushForPatch( pPatch, true );
  1349.         Select_Brush( pb );
  1350.         g_bScreenUpdates = true;
  1351.         Sys_UpdateWindows(W_ALL);
  1352.     }
  1353.     else
  1354.     {
  1355.         brush_t *pBrush = reinterpret_cast<brush_t *>( m_PatchesHandles.GetAt(index) );
  1356.         patchMesh_t *pPatch = pBrush->pPatch;
  1357.         pPatch->width = pMesh->width;
  1358.         pPatch->height = pMesh->height;
  1359.         pPatch->contents = pMesh->contents;
  1360.         pPatch->flags = pMesh->flags;
  1361.         pPatch->value = pMesh->value;
  1362.         pPatch->type = pMesh->type;
  1363.         memcpy( pPatch->ctrl, pMesh->ctrl, sizeof(drawVert_t)*MAX_PATCH_HEIGHT*MAX_PATCH_WIDTH );
  1364.         pPatch->bDirty = true;
  1365.     }
  1366. }
  1367.  
  1368. // this gets called when the plugin needs specific services, for example the OpenGL drawing interface
  1369. //++timo plugins should be able to dynamically register their own interfaces in there
  1370. int WINAPI QERApp_RequestInterface( REFGUID refGUID, LPVOID pInterface )
  1371. {
  1372.     if (IsEqualGUID( refGUID, QERQglTable_GUID ))
  1373.     {
  1374.         _QERQglTable *pQglTable = static_cast<_QERQglTable *>(pInterface);
  1375.         if ( pQglTable->m_nSize != sizeof(_QERQglTable) )
  1376.         {
  1377.             Sys_Printf("wrong m_nSize in plugin-requested _QERQglTable interface\n");
  1378.             return 0;
  1379.         }
  1380.         pQglTable->m_pfn_qglAlphaFunc = qglAlphaFunc;
  1381.         pQglTable->m_pfn_qglBegin = qglBegin;
  1382.         pQglTable->m_pfn_qglBindTexture = qglBindTexture;
  1383.         pQglTable->m_pfn_qglBlendFunc = qglBlendFunc;
  1384.         pQglTable->m_pfn_qglCallList = qglCallList;
  1385.         pQglTable->m_pfn_qglCallLists = qglCallLists;
  1386.         pQglTable->m_pfn_qglClear = qglClear;
  1387.         pQglTable->m_pfn_qglClearColor = qglClearColor;
  1388.         pQglTable->m_pfn_qglClearDepth = qglClearDepth;
  1389.         pQglTable->m_pfn_qglColor3f = qglColor3f;
  1390.         pQglTable->m_pfn_qglColor4f = qglColor4f;
  1391.         pQglTable->m_pfn_qglCullFace = qglCullFace;
  1392.         pQglTable->m_pfn_qglDisable = qglDisable;
  1393.         pQglTable->m_pfn_qglDeleteLists = qglDeleteLists;
  1394.         pQglTable->m_pfn_qglEnable = qglEnable;
  1395.         pQglTable->m_pfn_qglEnd = qglEnd;
  1396.         pQglTable->m_pfn_qglEndList = qglEndList;
  1397.         pQglTable->m_pfn_qglGenLists = qglGenLists;
  1398.         pQglTable->m_pfn_qglListBase = qglListBase;
  1399.         pQglTable->m_pfn_qglLoadIdentity = qglLoadIdentity;
  1400.         pQglTable->m_pfn_qglMatrixMode = qglMatrixMode;
  1401.         pQglTable->m_pfn_qglNewList = qglNewList;
  1402.         pQglTable->m_pfn_qglNormal3f = qglNormal3f;
  1403.         pQglTable->m_pfn_qglOrtho = qglOrtho;
  1404.         pQglTable->m_pfn_qglPointSize = qglPointSize;
  1405.         pQglTable->m_pfn_qglPolygonMode = qglPolygonMode;
  1406.         pQglTable->m_pfn_qglPopMatrix = qglPopMatrix;
  1407.         pQglTable->m_pfn_qglPushMatrix = qglPushMatrix;
  1408.         pQglTable->m_pfn_qglRotated = qglRotated;
  1409.         pQglTable->m_pfn_qglRotatef = qglRotatef;
  1410.         pQglTable->m_pfn_qglScalef = qglScalef;
  1411.         pQglTable->m_pfn_qglTexCoord2f = qglTexCoord2f;
  1412.         pQglTable->m_pfn_qglTexEnvf = qglTexEnvf;
  1413.         pQglTable->m_pfn_qglTexGenf = qglTexGenf;
  1414.         pQglTable->m_pfn_qglTexParameterf = qglTexParameterf;
  1415.         pQglTable->m_pfn_qglTranslated = qglTranslated;
  1416.         pQglTable->m_pfn_qglTranslatef = qglTranslatef;
  1417.         pQglTable->m_pfn_qglVertex2f = qglVertex2f;
  1418.         pQglTable->m_pfn_qglVertex3f = qglVertex3f;
  1419.         pQglTable->m_pfn_qglViewport = qglViewport;
  1420.         pQglTable->m_pfn_QE_CheckOpenGLForErrors = &QE_CheckOpenGLForErrors;
  1421.         pQglTable->m_pfn_QEW_SetupPixelFormat = &QEW_SetupPixelFormat;
  1422.         pQglTable->m_pfn_qwglCreateContext = qwglCreateContext;
  1423.         pQglTable->m_pfn_qwglDeleteContext = qwglDeleteContext;
  1424.         pQglTable->m_pfn_qwglMakeCurrent = qwglMakeCurrent;
  1425.         pQglTable->m_pfn_qwglShareLists = qwglShareLists;
  1426.         pQglTable->m_pfn_qwglSwapBuffers = qwglSwapBuffers;
  1427.         pQglTable->m_pfn_qwglUseFontBitmaps = qwglUseFontBitmaps;
  1428.         pQglTable->m_pfnGetQeglobalsHGLRC = &QERApp_GetQeglobalsHGLRC;
  1429.         pQglTable->m_pfn_qgluPerspective = qgluPerspective;
  1430.         pQglTable->m_pfn_qgluLookAt = qgluLookAt;
  1431.         pQglTable->m_pfnHookXYGLWindow = QERApp_HookXYGLWindow;
  1432.         pQglTable->m_pfnUnHookGLWindow = QERApp_UnHookGLWindow;
  1433.  
  1434.         return 1;
  1435.     }
  1436.     else if (IsEqualGUID( refGUID, QERSelectedFaceTable_GUID ))
  1437.     {
  1438.         _QERSelectedFaceTable *pSelectedFaceTable = static_cast<_QERSelectedFaceTable *>(pInterface);
  1439.         if ( pSelectedFaceTable->m_nSize != sizeof(_QERSelectedFaceTable) )
  1440.         {
  1441.             Sys_Printf("wrong m_nSize in plugin-requested _QERSelectedFaceTable interface\n");
  1442.             return 0;
  1443.         }
  1444.         pSelectedFaceTable->m_pfnGetTextureNumber = &QERApp_ISelectedFace_GetTextureNumber;
  1445.         pSelectedFaceTable->m_pfnGetFaceInfo = &QERApp_GetFaceInfo;
  1446.         pSelectedFaceTable->m_pfnSetFaceInfo = &QERApp_SetFaceInfo;
  1447.         pSelectedFaceTable->m_pfnGetTextureSize = &QERApp_GetTextureSize;
  1448.         pSelectedFaceTable->m_pfnTextureForName = &QERApp_Texture_ForName;
  1449.         pSelectedFaceTable->m_pfnSelect_SetTexture = &Select_SetTexture;
  1450.         return 1;
  1451.     }
  1452.     else if (IsEqualGUID( refGUID, QERPluginEntitiesTable_GUID ))
  1453.     {
  1454.         _QERPluginEntitiesTable *pPluginEntitiesTable = static_cast<_QERPluginEntitiesTable *>(pInterface);
  1455.         if ( pPluginEntitiesTable->m_nSize != sizeof(_QERPluginEntitiesTable) )
  1456.         {
  1457.             Sys_Printf("wrong m_nSize in plugin-requested _QERPluginEntitiesTable interface\n");
  1458.             return 0;
  1459.         }
  1460.         pPluginEntitiesTable->m_pfnEClassScanDir = &QERApp_EClassScanDir;
  1461.         return 1;
  1462.     }
  1463.     else if (IsEqualGUID( refGUID, QERScripLibTable_GUID ))
  1464.     {
  1465.         _QERScripLibTable *pScripLibTable = static_cast<_QERScripLibTable *>(pInterface);
  1466.         if ( pScripLibTable->m_nSize != sizeof( _QERScripLibTable ) )
  1467.         {
  1468.             Sys_Printf("wrong m_nSize in plugin-requested _QERScripLibTable\n");
  1469.             return 0;
  1470.         }
  1471.         pScripLibTable->m_pfnGetToken = &GetToken;
  1472.         pScripLibTable->m_pfnToken = &QERApp_Token;
  1473.         pScripLibTable->m_pfnUnGetToken = &UngetToken;
  1474.         return 1;
  1475.     }
  1476.     else if (IsEqualGUID( refGUID, QERAppSurfaceTable_GUID ))
  1477.     {
  1478.         _QERAppSurfaceTable *pSurfaceTable = static_cast<_QERAppSurfaceTable *>(pInterface);
  1479.         if ( pSurfaceTable->m_nSize != sizeof( _QERAppSurfaceTable ) )
  1480.         {
  1481.             Sys_Printf("wrong m_nSize in plugin-requested _QERAppSurfaceTable\n");
  1482.             return 0;
  1483.         }
  1484.         pSurfaceTable->m_pfnAnyPatchesSelected = &AnyPatchesSelected;
  1485.         pSurfaceTable->m_pfnOnlyPatchesSelected = &OnlyPatchesSelected;
  1486.         pSurfaceTable->m_pfnQeglobalsTexturewin = &QERApp_QeglobalsTexturewin;
  1487.         pSurfaceTable->m_pfnGetSelectedPatch = &QERApp_GetSelectedPatch;
  1488.         pSurfaceTable->m_pfnPatchRebuild = &Patch_Rebuild;
  1489.         pSurfaceTable->m_pfnGetTwoSelectedPatch = &QERApp_GetTwoSelectedPatch;
  1490.         return 1;
  1491.     }
  1492.     else if (IsEqualGUID( refGUID, QERAppBSPFrontendTable_GUID ))
  1493.     {
  1494.         _QERAppBSPFrontendTable *pBSPFrontendTable = static_cast<_QERAppBSPFrontendTable *>(pInterface);
  1495.         if ( pBSPFrontendTable->m_nSize != sizeof( _QERAppBSPFrontendTable ) )
  1496.         {
  1497.             Sys_Printf("wrong m_nSize in plugin-requested _QERAppBSPFrontendTable\n");
  1498.             return 0;
  1499.         }
  1500.         pBSPFrontendTable->m_pfnGetMapName = &QERApp_GetMapName;
  1501.         pBSPFrontendTable->m_pfnLoadPointFile = &Pointfile_Check;
  1502.         return 1;
  1503.     }
  1504.     else if (IsEqualGUID( refGUID, QERMessaging_GUID ))
  1505.     {
  1506.         _QERMessagingTable *pMessagingTable = static_cast<_QERMessagingTable *>(pInterface);
  1507.         if ( pMessagingTable->m_nSize != sizeof( _QERMessagingTable ) )
  1508.         {
  1509.             Sys_Printf("wrong m_nSize in plugin-requested _QERMessagingTable\n");
  1510.             return 0;
  1511.         }
  1512.         pMessagingTable->m_pfnHookWindow = QERApp_HookWindow;
  1513.         pMessagingTable->m_pfnUnHookWindow = QERApp_UnHookWindow;
  1514.         pMessagingTable->m_pfnGetXYWndWrapper = QERApp_GetXYWndWrapper;
  1515.         pMessagingTable->m_pfnHookListener = QERApp_HookListener;
  1516.         pMessagingTable->m_pfnUnHookListener = QERApp_UnHookListener;
  1517.         return 1;
  1518.     }
  1519.     else if (IsEqualGUID( refGUID, QERShadersTable_GUID ))
  1520.     {
  1521.         _QERShadersTable *pShadersTable = static_cast<_QERShadersTable *>(pInterface);
  1522.         if ( pShadersTable->m_nSize != sizeof( _QERShadersTable ) )
  1523.         {
  1524.             Sys_Printf("wring m_nSize in plugin-requested _QERShadersTable\n");
  1525.             return 0;
  1526.         }
  1527.         pShadersTable->m_pfnTryTextureForName = QERApp_TryTextureForName;
  1528.         return 1;
  1529.     }
  1530.     return 0;
  1531. }
  1532.  
  1533. int CPlugInManager::FillFuncTable(CPlugIn *pPlug)
  1534. {
  1535.   _QERFuncTable_1 *pTable = reinterpret_cast<_QERFuncTable_1*>(pPlug->getFuncTable());
  1536.   if (pTable != NULL)
  1537.   {
  1538.     if (pTable->m_fVersion != QER_PLUG_VERSION)
  1539.     {
  1540.       Sys_Printf("Radiant plugin manager was built with version %.2f, Plugin %s is version %.2f\n", QER_PLUG_VERSION, pPlug->getVersionStr() , pTable->m_fVersion);
  1541.     }
  1542.     if (pTable->m_fVersion >= QER_PLUG_VERSION_1)
  1543.     {
  1544.       pTable->m_pfnCreateBrush = &QERApp_CreateBrush;
  1545.       pTable->m_pfnCreateBrushHandle = &QERApp_CreateBrushHandle;
  1546.       pTable->m_pfnDeleteBrushHandle = &QERApp_DeleteBrushHandle;
  1547.       pTable->m_pfnCommitBrushHandle = &QERApp_CommitBrushHandleToMap;
  1548.       pTable->m_pfnAddFace = &QERApp_AddFace;
  1549.       pTable->m_pfnAddFaceData = &QERApp_AddFaceData;
  1550.       pTable->m_pfnGetFaceData = &QERApp_GetFaceData;
  1551.       pTable->m_pfnGetFaceCount = &QERApp_GetFaceCount;
  1552.       pTable->m_pfnSetFaceData = &QERApp_SetFaceData;
  1553.       pTable->m_pfnDeleteFace = &QERApp_DeleteFace;
  1554.       pTable->m_pfnTextureBrush = &QERApp_TextureBrush;
  1555.       pTable->m_pfnBuildBrush = &QERApp_BuildBrush;                        // PGM
  1556.         pTable->m_pfnSelectBrush = &QERApp_SelectBrush;                    // PGM
  1557.       pTable->m_pfnDeselectBrush = &QERApp_DeselectBrush;                // PGM
  1558.       pTable->m_pfnDeselectAllBrushes = &QERApp_DeselectAllBrushes;        // PGM
  1559.       pTable->m_pfnDeleteSelection = &QERApp_DeleteSelection;
  1560.       pTable->m_pfnGetPoints = &QERApp_GetPoints;
  1561.       pTable->m_pfnSysMsg = &QERApp_SysMsg;
  1562.       pTable->m_pfnInfoMsg = &QERApp_InfoMsg;
  1563.       pTable->m_pfnHideInfoMsg = &QERApp_HideInfoMsg;
  1564.       pTable->m_pfnPositionView = &QERApp_PositionView;                    // PGM
  1565.       pTable->m_pfnSelectedBrushCount = &QERApp_SelectedBrushCount;
  1566.       pTable->m_pfnAllocateSelectedBrushHandles  = &QERApp_AllocateSelectedBrushHandles;
  1567.       pTable->m_pfnReleaseSelectedBrushHandles  = &QERApp_ReleaseSelectedBrushHandles;
  1568.       pTable->m_pfnGetSelectedBrushHandle = &QERApp_GetSelectedBrushHandle;
  1569.       pTable->m_pfnActiveBrushCount = &QERApp_ActiveBrushCount;
  1570.       pTable->m_pfnAllocateActiveBrushHandles = &QERApp_AllocateActiveBrushHandles;
  1571.       pTable->m_pfnReleaseActiveBrushHandles = &QERApp_ReleaseActiveBrushHandles;
  1572.       pTable->m_pfnGetActiveBrushHandle = &QERApp_GetActiveBrushHandle;
  1573.       pTable->m_pfnTextureCount = &QERApp_TextureCount;
  1574.       pTable->m_pfnGetTexture = &QERApp_GetTexture;
  1575.       pTable->m_pfnGetCurrentTexture = &QERApp_GetCurrentTexture;
  1576.       pTable->m_pfnSetCurrentTexture = &QERApp_SetCurrentTexture;
  1577.       pTable->m_pfnGetEClassCount = &QERApp_GetEClassCount;
  1578.       pTable->m_pfnGetEClass = &QERApp_GetEClass;
  1579.       pTable->m_pfnResetPlugins = &QERApp_ResetPlugins;
  1580.     }
  1581.     // end of v1.00
  1582.     if (pTable->m_fVersion >= 1.5f)
  1583.     {
  1584.       // v1.50 starts
  1585.       pTable->m_pfnLoadTextureRGBA = &QERApp_LoadTextureRGBA;
  1586.       // end of v1.50
  1587.     }
  1588.     if (pTable->m_fVersion >= 1.7f)
  1589.     {
  1590.         pTable->m_pfnGetEntityCount = &QERApp_GetEntityCount;
  1591.         pTable->m_pfnGetEntityHandle = &QERApp_GetEntityHandle;
  1592.         pTable->m_pfnGetEntityKeyValList = &QERApp_GetEntityKeyValList;
  1593.         pTable->m_pfnAllocateEpair = &QERApp_AllocateEpair;
  1594.         pTable->m_pfnSetEntityKeyValList = &QERApp_SetEntityKeyValList;
  1595.         pTable->m_pfnAllocateEntityBrushHandles = &QERApp_AllocateEntityBrushHandles;
  1596.         pTable->m_pfnReleaseEntityBrushHandles = &QERApp_ReleaseEntityBrushHandles;
  1597.         pTable->m_pfnGetEntityBrushHandle = &QERApp_GetEntityBrushHandle;
  1598.         pTable->m_pfnCreateEntityHandle = &QERApp_CreateEntityHandle;
  1599.         pTable->m_pfnCommitBrushHandleToEntity = &QERApp_CommitBrushHandleToEntity;
  1600.         pTable->m_pfnCommitEntityHandleToMap = &QERApp_CommitEntityHandleToMap;
  1601.         pTable->m_pfnSetScreenUpdate = &QERApp_SetScreenUpdate;
  1602.         pTable->m_pfnSysUpdateWindows = &Sys_UpdateWindows;
  1603.         pTable->m_pfnBuildBrush2 = &QERApp_BuildBrush2;
  1604.         pTable->m_pfnReadProjectKey = &QERApp_ReadProjectKey;
  1605.         pTable->m_pfnScanFileForEClass = &QERApp_ScanFileForEClass;
  1606.         pTable->m_pfnRequestInterface = &QERApp_RequestInterface;
  1607.         pTable->m_pfnErrorMsg = &QERApp_ErrorMsg;
  1608.         pTable->m_pfnLoadFile = &QERApp_LoadFile;
  1609.         pTable->m_pfnExpandReletivePath = &QERApp_ExpandReletivePath;
  1610.         pTable->m_pfnQE_ConvertDOSToUnixName = &QE_ConvertDOSToUnixName;
  1611.         pTable->m_pfnHasShader = &QERApp_HasShader;
  1612.         pTable->m_pfnTexture_LoadSkin = &Texture_LoadSkin;
  1613.         pTable->m_pfnRadiantFree = &QERApp_RadiantFree;
  1614.         pTable->m_pfnGetGamePath = &QERApp_GetGamePath;
  1615.         pTable->m_pfnGetQERPath = &QERApp_GetQERPath;
  1616.         // patches
  1617.         pTable->m_pfnAllocateActivePatchHandles = &QERApp_AllocateActivePatchHandles;
  1618.         pTable->m_pfnAllocateSelectedPatchHandles = &QERApp_AllocateSelectedPatchHandles;
  1619.         pTable->m_pfnReleasePatchHandles = &QERApp_ReleasePatchHandles;
  1620.         pTable->m_pfnGetPatchData = &QERApp_GetPatchData;
  1621.         pTable->m_pfnDeletePatch = &QERApp_DeletePatch;
  1622.         pTable->m_pfnCreatePatchHandle = &QERApp_CreatePatchHandle;
  1623.         pTable->m_pfnCommitPatchHandleToMap = &QERApp_CommitPatchHandleToMap;
  1624.     }
  1625.     return true;
  1626.   }
  1627.   else
  1628.   {
  1629.     Sys_Printf("Unable to load %s because the function tables are not the same size\n", pPlug->getVersionStr());
  1630.   }
  1631.   return false;
  1632. }
  1633.  
  1634. CPlugIn * CPlugInManager::PluginForModule(HMODULE hPlug)
  1635. {
  1636.     int i;
  1637.     for( i=0; i!=m_PlugIns.GetSize(); i++ )
  1638.     {
  1639.         if ( reinterpret_cast<CPlugIn *>(m_PlugIns[i])->GetDLLModule() == hPlug )
  1640.             return reinterpret_cast<CPlugIn *>(m_PlugIns[i]);
  1641.     }
  1642.     return NULL;
  1643. }
  1644.  
  1645.